﻿using System;
using System.Collections.Generic;
using System.Linq;
using ArchPostprocessing.CompoundStructureManage.DataDefinition;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using YJKArch.Utils;

namespace ArchPostprocessing.CompoundStructureManage.Managers
{
	public class WallCommon
	{
		public static bool SelectWalls(UIDocument uiDoc, ref List<Wall> selWalls)
		{
			bool result;
			try
			{
				foreach (Reference reference in uiDoc.Selection.PickObjects((Autodesk.Revit.UI.Selection.ObjectType)1, new WallFilter(), "请选择墙："))
				{
					Wall item = uiDoc.Document.GetElement(reference) as Wall;
					selWalls.Add(item);
				}
				if (selWalls.Count == 0)
				{
					result = false;
				}
				else
				{
					result = true;
				}
			}
			catch (Exception)
			{
				result = false;
			}
			return result;
		}

		public static void GetWalls(Autodesk.Revit.DB.Document doc, ref List<Wall> selWalls)
		{
			foreach (Element element in new FilteredElementCollector(doc, doc.ActiveView.Id).OfClass(typeof(Wall)).ToElements())
			{
				Wall item = element as Wall;
				selWalls.Add(item);
			}
		}

		public static Wall CreateWall(Autodesk.Revit.DB.Document doc, Curve curve, WallType wallType, double height)
		{
			Wall result;
			try
			{
				if (curve == null)
				{
					result = null;
				}
				else
				{
					result = Wall.Create(doc, curve, wallType.Id, doc.ActiveView.GenLevel.Id, height, 0.0, false, false);
				}
			}
			catch (Exception ex)
			{
				string message = ex.Message;
				result = null;
			}
			return result;
		}

		public static void GetWallElevationInfo(Wall wall, Autodesk.Revit.DB.Document doc, ref double wallElevation, ref double wallHeight)
		{
			ElementId elementId = wall.get_Parameter(BuiltInParameter.WALL_BASE_CONSTRAINT).AsElementId();
			double elevation = (doc.GetElement(elementId) as Level).Elevation;
			double num = wall.get_Parameter(BuiltInParameter.WALL_BASE_OFFSET).AsDouble();
			wallElevation = elevation + num;
			ElementId elementId2 = wall.get_Parameter(BuiltInParameter.WALL_HEIGHT_TYPE).AsElementId();
			if (elementId2 == ElementId.InvalidElementId)
			{
				double num2 = wall.get_Parameter(BuiltInParameter.WALL_USER_HEIGHT_PARAM).AsDouble();
				wallHeight = num2;
				return;
			}
			Level level = doc.GetElement(elementId2) as Level;
			double num3 = wall.get_Parameter(BuiltInParameter.WALL_TOP_OFFSET).AsDouble();
			wallHeight = level.Elevation + num3 - wallElevation;
		}

		public static void JoinWalls(List<OffsetWallInfo> offsetWallInfoList, Autodesk.Revit.DB.Document doc, bool bWithoutTransaction = false)
		{
			Transaction transaction = null;
			if (!bWithoutTransaction)
			{
				transaction = new Transaction(doc);
				transaction.Start("join wall");
			}
			foreach (OffsetWallInfo offsetWallInfo in offsetWallInfoList)
			{
				Element element = doc.GetElement(offsetWallInfo.ReferencePole.ComponentId);
				List<Element> negativeWalls = offsetWallInfo.NegativeWalls;
				negativeWalls.Insert(0, element);
				WallCommon.JoinElements(negativeWalls, doc);
				List<Element> positiveWalls = offsetWallInfo.PositiveWalls;
				positiveWalls.Insert(0, element);
				WallCommon.JoinElements(positiveWalls, doc);
			}
			if (!bWithoutTransaction)
			{
				transaction.Commit();
			}
		}

		public static Wall FindMainWall(List<Wall> walls, Autodesk.Revit.DB.Document doc)
		{
			int num = -1;
			return WallCommon.FindMainWall(walls, doc, ref num);
		}

		public static Curve GetOffsetWallLocation(Curve centerLine, XYZ orientation, double offsetSpace)
		{
			XYZ endPoint = centerLine.GetEndPoint(0);
			XYZ endPoint2 = centerLine.GetEndPoint(1);
			Curve result;
			if (centerLine.GetType() == typeof(Line))
			{
				XYZ xyz = endPoint + orientation * offsetSpace;
				XYZ xyz2 = endPoint2 + orientation * offsetSpace;
				result = Line.CreateBound(xyz, xyz2);
			}
			else
			{
				XYZ center = (centerLine as Arc).Center;
				XYZ xyz3 = Geometry.CalculatMidPoint(centerLine as Arc);
				XYZ xyz4 = (endPoint - center).Normalize();
				XYZ xyz5 = (endPoint2 - center).Normalize();
				XYZ xyz6 = (xyz3 - center).Normalize();
				if (!Geometry.IsEqual(orientation, xyz4) && !Geometry.IsEqual(orientation, xyz5))
				{
					xyz4 = -xyz4;
					xyz5 = -xyz5;
					xyz6 = -xyz6;
				}
				XYZ xyz7 = endPoint + xyz4 * offsetSpace;
				XYZ xyz8 = endPoint2 + xyz5 * offsetSpace;
				XYZ xyz9 = xyz3 + xyz6 * offsetSpace;
				result = Arc.Create(xyz7, xyz8, xyz9);
			}
			return result;
		}

		public static void SetKeyRefParam(Wall wall)
		{
			Parameter parameter = wall.get_Parameter(BuiltInParameter.WALL_KEY_REF_PARAM);
			if (parameter == null)
			{
				return;
			}
			parameter.Set(0);
		}

		public static Wall FindMainWall(List<Wall> walls, Autodesk.Revit.DB.Document doc, ref int index)
		{
			for (int i = 0; i < walls.Count; i++)
			{
				IList<ElementId> list = walls[i].FindInserts(true, true, true, true);
				if (list.Count != 0)
				{
					Element element = doc.GetElement(list[0]);
					if (!(element.GetType() != typeof(FamilyInstance)) && (element as FamilyInstance).Host.Id.IntegerValue == walls[i].Id.IntegerValue)
					{
						index = i;
						return walls[i];
					}
				}
			}
			for (int i = 0; i < walls.Count; i++)
			{
				using (List<CompoundStructureLayer>.Enumerator enumerator = walls[i].WallType.GetCompoundStructure().GetLayers().ToList<CompoundStructureLayer>().GetEnumerator())
				{
					while (enumerator.MoveNext())
					{
						if ((int)enumerator.Current.Function == 1)
						{
							index = i;
							return walls[i];
						}
					}
				}
			}
			index = 0;
			return walls[0];
		}

		private static void JoinElements(List<Element> elements, Autodesk.Revit.DB.Document doc)
		{
			for (int i = 1; i < elements.Count; i++)
			{
				try
				{
					if (!JoinGeometryUtils.AreElementsJoined(doc, elements[i - 1], elements[i]))
					{
						JoinGeometryUtils.JoinGeometry(doc, elements[i - 1], elements[i]);
					}
				}
				catch (Exception)
				{
				}
			}
		}
	}
}
